home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
376-400
/
disk_386
/
xlispstat
/
src2.lzh
/
XLisp-Stat
/
linalg.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-04
|
24KB
|
939 lines
/* linalg - Lisp interface for basic linear algebra routines */
/* XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney */
/* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz */
/* You may give out copies of this software; for conditions see the */
/* file COPYING included with this distribution. */
#include <stdlib.h>
#include "xlisp.h"
#include "osdef.h"
#ifdef ANSI
#include "xlproto.h"
#include "xlsproto.h"
#else
#include "xlfun.h"
#include "xlsfun.h"
#endif ANSI
#include "xlsvar.h"
#ifdef ANSI
LVAL vector_to_data(Vector,int,int,int),matrix_to_data(Matrix,int,int,int),
kernel(int),
add_contour_point(int,int,int,int,RVector,RVector,RMatrix,double,LVAL);
char *allocate(unsigned,unsigned);
void free_alloc(void *),baddata(LVAL),badmatrix(LVAL),badsquarematrix(LVAL),
badsequence(LVAL),
get_smoother_data(Vector *,Vector *,int *,Vector *,Vector *,int *,int);
int data_mode(LVAL);
Vector data_to_vector(LVAL,int);
Matrix data_to_matrix(LVAL,int);
#else
LVAL vector_to_data(),matrix_to_data(),
kernel(),
add_contour_point();
char *allocate();
void free_alloc(),baddata(),badmatrix(),badsquarematrix(),
badsequence(),
get_smoother_data();
int data_mode();
Vector data_to_vector();
Matrix data_to_matrix();
#endif ANSI
/************************************************************************/
/** **/
/** Storage Allocation Functions **/
/** **/
/************************************************************************/
static char *allocate(n, m)
unsigned n, m;
{
char *p = calloc(n, m);
if (p == nil) xlfail("allocation failed");
return(p);
}
static void free_alloc(p)
/* char*/ void *p;/* changed JKL */
{
if (p != nil) free(p);
}
IVector ivector(n)
unsigned n;
{
return((IVector) allocate(n, sizeof(int)));
}
RVector rvector(n)
unsigned n;
{
return((RVector) allocate(n, sizeof(double)));
}
CVector cvector(n)
unsigned n;
{
return((CVector) allocate(n, sizeof(Complex)));
}
void free_vector(v) Vector v; { free_alloc(v); }
IMatrix imatrix(n, m)
unsigned n, m;
{
int i;
IMatrix mat = (IMatrix) allocate(n, sizeof(IVector));
for (i = 0; i < n; i++) mat[i] = (IVector) allocate(m, sizeof(int));
return(mat);
}
RMatrix rmatrix(n, m)
unsigned n, m;
{
int i;
RMatrix mat = (RMatrix) allocate(n, sizeof(RVector));
for (i = 0; i < n; i++) mat[i] = (RVector) allocate(m, sizeof(double));
return(mat);
}
CMatrix cmatrix(n, m)
unsigned n, m;
{
int i;
CMatrix mat = (CMatrix) allocate(n, sizeof(CVector));
for (i = 0; i < n; i++) mat[i] = (CVector) allocate(m, sizeof(Complex));
return(mat);
}
void free_matrix(mat, n)
Matrix mat;
int n;
{
int i;
if (mat != nil) for (i = 0; i < n; i++) free_alloc(mat[i]);
free_alloc(mat);
}
/************************************************************************/
/** **/
/** Lisp to/from C Data Translation Functions **/
/** **/
/************************************************************************/
static void baddata(data)
LVAL data;
{
xlerror("bad linear algebra data", data);
}
static void badmatrix(data)
LVAL data;
{
xlerror("not a matrix", data);
}
static void badsquarematrix(data)
LVAL data;
{
xlerror("not a square matrix", data);
}
static void badsequence(data)
LVAL data;
{
xlerror("not a sequence", data);
}
static int data_mode(data)
LVAL data;
{
LVAL item;
int i, n;
int mode = IN;
if (! consp(data) && ! vectorp(data) && ! displacedarrayp(data))
baddata(data);
if (! consp(data)) data = arraydata(data);
n = seqlen(data);
for (i = 0; i < n; i++) {
item = getnextelement(&data, i);
if (! realp(item) && ! complexp(item)) baddata(item);
if (floatp(item) && mode == IN) mode = RE;
else if (complexp(item)) mode = CX;
}
return(mode);
}
static Vector data_to_vector(data, mode)
LVAL data;
int mode;
{
LVAL item;
int i, n;
Vector v;
IVector iv;
RVector rv;
CVector cv;
if (! sequencep(data)) baddata(data);
n = seqlen(data);
switch (mode) {
case IN: iv = ivector(n); v = (Vector) iv; break;
case RE: rv = rvector(n); v = (Vector) rv; break;
case CX: cv = cvector(n); v = (Vector) cv; break;
}
for (i = 0; i < n; i++) {
item = getnextelement(&data, i);
switch (mode) {
case IN: iv[i] = getfixnum(item); break;
case RE: rv[i] = makedouble(item); break;
case CX: cv[i] = makecomplex(item); break;
}
}
return(v);
}
static Matrix data_to_matrix(data, mode)
LVAL data;
int mode;
{
LVAL item;
int i, j, n, m;
Matrix mat;
IMatrix imat;
RMatrix rmat;
CMatrix cmat;
if (! matrixp(data)) baddata(data);
n = numrows(data); m = numcols(data);
switch (mode) {
case IN: imat = imatrix(n, m); mat = (Matrix) imat; break;
case RE: rmat = rmatrix(n, m); mat = (Matrix) rmat; break;
case CX: cmat = cmatrix(n, m); mat = (Matrix) cmat; break;
}
data = arraydata(data);
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
item = getelement(data, i * m + j);
switch (mode) {
case IN: imat[i][j] = getfixnum(item); break;
case RE: rmat[i][j] = makedouble(item); break;
case CX: cmat[i][j] = makecomplex(item); break;
}
}
}
return(mat);
}
static LVAL vector_to_data(v, n, mode, as_list)
Vector v;
int n, mode, as_list;
{
LVAL data;
int i;
IVector iv = (IVector) v;
RVector rv = (RVector) v;
CVector cv = (CVector) v;
xlsave1(data);
data = newvector(n);
for (i = 0; i < n; i++) {
switch (mode) {
case IN: setelement(data, i, cvfixnum((FIXTYPE) iv[i])); break;
case RE: setelement(data, i, cvflonum((FLOTYPE) rv[i])); break;
case CX: setelement(data, i, cvcomplex(cv[i])); break;
}
}
if (as_list) data = coerce_to_list(data);
xlpop();
return(data);
}
static LVAL matrix_to_data(mat, n, m, mode)
Matrix mat;
int n, m, mode;
{
LVAL data, dim, data_matrix;
int i, j;
IMatrix imat = (IMatrix) mat;
RMatrix rmat = (RMatrix) mat;
CMatrix cmat = (CMatrix) mat;
xlstkcheck(2);
xlsave(dim);
xlsave(data_matrix);
dim = integer_list_2(n, m);
data_matrix = newarray(dim, NIL, NIL);
data = arraydata(data_matrix);
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
switch (mode) {
case IN: setelement(data, i * m + j, cvfixnum((FIXTYPE) imat[i][j])); break;
case RE: setelement(data, i * m + j, cvflonum((FLOTYPE) rmat[i][j])); break;
case CX: setelement(data, i * m + j, cvcomplex(cmat[i][j])); break;
}
}
}
xlpopn(2);
return(data_matrix);
}
/************************************************************************/
/** **/
/** Machine Epsilon Determination **/
/** **/
/************************************************************************/
double macheps()
{
static int calculated = FALSE;
static double epsilon = 1.0;
if (! calculated)
while (1.0 + epsilon / 2.0 != 1.0) epsilon = epsilon / 2.0;
calculated = TRUE;
return(epsilon);
}
/************************************************************************/
/** **/
/** Lisp Interfaces to Linear Algebra Routines **/
/** **/
/************************************************************************/
LVAL xslu_decomp()
{
LVAL data, result, temp;
Matrix mat;
IVector iv;
double d;
int n, m, mode, singular;
data = xlgetarg();
xllastarg();
if (! matrixp(data)) badmatrix(data);
n = numrows(data);
m = numcols(data);
if (n != m || n <= 0 || m <= 0) badsquarematrix(data);
xlsave1(result);
result = mklist(4, NIL); /* redundant assignment to nil in macro JKL */
temp = result;
mode = data_mode(data);
if (mode == IN) mode = RE;
mat = data_to_matrix(data, mode);
iv = ivector(n);
singular = crludcmp(mat, n, iv, mode, &d);
rplaca(temp, matrix_to_data(mat, n, n, mode)); temp = cdr(temp);
rplaca(temp, vector_to_data((Vector)iv, n, IN, FALSE)); temp = cdr(temp);
rplaca(temp, cvflonum((FLOTYPE) d)); temp = cdr(temp);
rplaca(temp, (singular) ? s_true : NIL);
free_matrix(mat, n);
free_vector((Vector)iv); /* casts added JKL */
xlpop();
return(result);
}
LVAL xslu_solve()
{
LVAL ludecomp, la, lindx, lb, result;
Matrix a;
Vector b, indx;
int n, m, a_mode, b_mode, mode, singular;
ludecomp = xlgalist();
lb = xlgetarg();
xllastarg();
la = (consp(ludecomp)) ? car(ludecomp) : NIL;
lindx = (consp(cdr(ludecomp))) ? car(cdr(ludecomp)) : NIL;
if (! matrixp(la)) badmatrix(la);
n = numrows(la);
m = numcols(la);
if (n != m || n <= 0 || m <= 0) badsquarematrix(la);
if (! sequencep(lindx)) badsequence(lindx);
if (data_mode(lindx) != IN) xlerror("not an integer sequence", lindx);
if (! sequencep(lb)) badsequence(lb);
if (seqlen(lb) != n) xlerror("bad sequence length", lb);
a_mode = data_mode(la);
b_mode = data_mode(lb);
mode = max(a_mode, b_mode);
if (mode == IN) mode = RE;
a = data_to_matrix(la, mode);
indx = data_to_vector(lindx, IN);
b = data_to_vector(lb, mode);
singular = crlubksb(a, n, (IVector)indx, b, mode);/* cast added JKL */
result = vector_to_data(b, n, mode, listp(lb));
free_matrix(a, n);
free_vector(indx);
free_vector(b);
if (singular) xlfail("matrix is (numerically) singular");
return(result);
}
LVAL xslu_determinant()
{
LVAL data, result;
Matrix mat;
CMatrix cmat;
RMatrix rmat;
IVector iv;
double d, rd1, d2, magn;
Complex cd1;
int m, n, i, mode;
data = xlgetarg();
xllastarg();
if (! matrixp(data)) badmatrix(data);
m = numrows(data);
n = numcols(data);
if (n != m || n <= 0 || m <= 0) badsquarematrix(data);
mode = data_mode(data);
if (mode == IN) mode = RE;
mat = data_to_matrix(data, mode);
iv = ivector(n);
crludcmp(mat, n, iv, mode, &d);
switch (mode) {
case RE:
rmat = (RMatrix) mat;
rd1 = d;
d2 = 0.0;
for (i = 0; i < n; i++) {
if ((magn = fabs(rmat[i][i])) == 0.0) {
rd1 = 0.0;
break;
}
rd1 *= rmat[i][i] / magn;
d2 += log(magn);
}
result = cvflonum((FLOTYPE) rd1 * exp(d2));
break;
case CX:
cmat = (CMatrix) mat;
cd1 = cart2complex(d, 0.0);
d2 = 0.0;
for (i = 0; i < n; i++) {
if ((magn = modulus(cmat[i][i])) == 0.0) {
cd1 = cart2complex(0.0, 0.0);
break;
}
cd1 = polar2complex(modulus(cd1), phase(cd1) + phase(cmat[i][i]));
d2 += log(magn);
}
result = cvcomplex(cmul(cd1, cart2complex(exp(d2), 0.0)));
break;
}
free_matrix(mat, n);
free_vector((Vector)iv);/* cast added JKL */
return(result);
}
LVAL xslu_inverse()
{
LVAL data, result;
Matrix mat, inv;
CMatrix cinv;
RMatrix rinv;
CVector cv;
RVector rv;
Vector v;
IVector iv;
double d;
int m, n, i, j, mode, singular;
data = xlgetarg();
xllastarg();
if (! matrixp(data)) badmatrix(data);
m = numrows(data);
n = numcols(data);
if (n != m || n <= 0 || m <= 0) badsquarematrix(data);
mode = data_mode(data);
if (mode == IN) mode = RE;
mat = data_to_matrix(data, mode);
iv = ivector(n);
inv = (mode == RE) ? (Matrix) rmatrix(n,n) : (Matrix) cmatrix(n,n);
rinv = (RMatrix) inv;
cinv = (CMatrix) inv;
v = (mode == RE) ? (Vector) rvector(n) : (Vector) cvector(n);
rv = (RVector) v;
cv = (CVector) v;
singular = crludcmp(mat, n, iv, mode, &d);
if (! singular) {
for (j = 0; j < n; j++) {
for (i = 0; i < n; i++) {
if (mode == RE) rv[i] = 0.0;
else cv[i] = cart2complex(0.0, 0.0);
}
if (mode == RE) rv[j] = 1.0;
else cv[j] = cart2complex(1.0, 0.0);
singular = singular || crlubksb(mat, n, iv, v, mode);
for (i = 0; i < n; i++) {
if (mode == RE) rinv[i][j] = rv[i];
else cinv[i][j] = cv[i];
}
}
result = matrix_to_data(inv, n, n, mode);
}
free_matrix(mat, n);
free_matrix(inv, n);
free_vector((Vector)iv);/* cast added JKL */
free_vector(v);
if (singular) xlfail("matrix is (numerically) singular");
return(result);
}
LVAL xssv_decomp()
{
LVAL data, result, temp;
Matrix mat, v;
Vector w;
int n, m, mode, converged;
data = xlgetarg();
xllastarg();
if (! matrixp(data)) badmatrix(data);
m = numrows(data);
n = numcols(data);
if (n <= 0 || m <= 0) baddata(data);
if (m < n) xlfail("number of rows less than number of columns");
xlsave1(result);
result = mklist(4, NIL);
temp = result;
mode = data_mode(data);
if (mode == IN) mode = RE;
if (mode == CX) xlfail("complex SVD not available yet");
mat = data_to_matrix(data, mode);
w = (Vector) rvector(n);
v = (Matrix) rmatrix(n, n);
/* casts added JKL */
converged = svdcmp((RMatrix)mat, m, n, (RVector)w, (RMatrix)v);
rplaca(temp, matrix_to_data(mat, m, n, mode)); temp = cdr(temp);
rplaca(temp, vector_to_data(w, n, mode, FALSE)); temp = cdr(temp);
rplaca(temp, matrix_to_data(v, n, n, mode)); temp = cdr(temp);
rplaca(temp, (converged) ? s_true : NIL);
free_matrix(mat, m);
free_matrix(v, n);
free_vector(w);
xlpop();
return(result);
}
LVAL xsqr_decomp()
{
LVAL data, result, temp;
Matrix mat, v;
Vector jpvt;
int n, m, mode, pivot;
data = xlgetarg();
pivot = (moreargs()) ? (xlgetarg() != NIL) : FALSE;
xllastarg();
if (! matrixp(data)) badmatrix(data);
m = numrows(data);
n = numcols(data);
if (n <= 0 || m <= 0) baddata(data);
if (m < n) xlfail("number of rows less than number of columns");
xlsave1(result);
result = mklist((pivot) ? 3 : 2, NIL);
temp = result;
mode = data_mode(data);
if (mode == IN) mode = RE;
if (mode == CX) xlfail("complex QR decomposition not available yet");
mat = data_to_matrix(data, mode);
v = (Matrix) rmatrix(n, n);
jpvt = (Vector) ivector(n);
/* casts added JKL */
qrdecomp((RMatrix)mat, m, n, (RMatrix)v, (IVector)jpvt, pivot);
rplaca(temp, matrix_to_data(mat, m, n, mode)); temp = cdr(temp);
rplaca(temp, matrix_to_data(v, n, n, mode)); temp = cdr(temp);
if (pivot) rplaca(temp, vector_to_data((Vector)jpvt, n, IN, TRUE));
free_matrix((Matrix)mat, m);/* casts added JKL */
free_matrix((Matrix)v, n);
free_vector((Vector)jpvt);
xlpop();
return(result);
}
LVAL xschol_decomp()
{
LVAL data, result;
Matrix mat;
int n, m, mode;
double maxadd, maxoffl;
data = xlgetarg();
if (moreargs()) maxoffl = makedouble(xlgetarg());
else maxoffl = 0.0;
xllastarg();
if (! matrixp(data)) badmatrix(data);
m = numrows(data);
n = numcols(data);
if (n != m || n <= 0 || m <= 0) badsquarematrix(data);
mode = data_mode(data);
if (mode == IN) mode = RE;
if (mode == CX) xlfail("complex Cholesky not available yet");
mat = data_to_matrix(data, mode);
choldecomp((RMatrix)mat, n, maxoffl, &maxadd);/* cast added JKL */
result = mklist(2, NIL);
rplaca(result, matrix_to_data(mat, n, n, mode));
rplaca(cdr(result), cvflonum((FLOTYPE) maxadd));
free_matrix(mat, m);
return(result);
}
LVAL xsrcondest()
{
LVAL data, result;
Matrix mat;
int n, m, mode;
double est;
data = xlgetarg();
xllastarg();
if (! matrixp(data)) badmatrix(data);
m = numrows(data);
n = numcols(data);
if (n != m || n <= 0 || m <= 0) badsquarematrix(data);
mode = data_mode(data);
if (mode == IN) mode = RE;
if (mode == CX) xlfail("complex condition estimate not available yet");
mat = data_to_matrix(data, mode);
est = rcondest((RMatrix)mat, n);/* cast added JKL */
result = cvflonum((FLOTYPE) est);
free_matrix(mat, m);
return(result);
}
LVAL xsmake_rotation()
{
LVAL s1, s2, result;
Vector x, y;
Matrix rot;
double alpha;
int n, use_alpha = FALSE;
s1 = xsgetsequence();
s2 = xsgetsequence();
if (moreargs()) {
use_alpha = TRUE;
alpha = makedouble(xlgetarg());
}
xllastarg();
n = seqlen(s1);
if (seqlen(s2) != n) xlfail("sequences not the same length");
if (data_mode(s1) == CX || data_mode(s2) == CX)
xlfail("complex data not supported yet");
x = data_to_vector(s1, RE);
y = data_to_vector(s2, RE);
rot = (Matrix) rmatrix(n,n);/* casts added JKL */
make_rotation(n, (RMatrix)rot, (RVector)x, (RVector)y, use_alpha, alpha);
result = matrix_to_data(rot, n, n, RE);
free_vector(x);
free_vector(y);
free_matrix(rot, n);
return(result);
}
#define NS_DEFAULT 30
static void get_smoother_data(px, py, pn, pxs, pys, pns, is_reg)
Vector *px, *py, *pxs, *pys;
int *pn, *pns, is_reg;
{
LVAL s1, s2, arg, sk_xvals = xlenter(":XVALS");
int n, ns, i, supplied;
double xmin, xmax, *x, *xs;
s1 = xsgetsequence();
if (is_reg) s2 = xsgetsequence();
if (xlgetkeyarg(sk_xvals, &arg)) {
if (! sequencep(arg) && ! fixp(arg)) xlbadtype(arg);
}
else arg = NIL;
ns = (fixp(arg)) ? getfixnum(arg) : seqlen(arg);
if (ns < 2) ns = NS_DEFAULT;
supplied = (sequencep(arg) && arg != NIL) ? TRUE : FALSE;
n = seqlen(s1);
if (n <= 0) xlfail("sequence too short");
if (is_reg && seqlen(s2) != n) xlfail("sequences not the same length");
if (supplied && data_mode(arg) == CX) xlfail("data must be real");
if (data_mode(s1) == CX || (is_reg && data_mode(s2) == CX))
xlfail("data must be real");
*px = data_to_vector(s1, RE);
*py = (is_reg) ? data_to_vector(s2, RE) : nil;
*pxs = (supplied) ? data_to_vector(arg, RE) : (Vector) rvector(ns);
*pys = (Vector) rvector(ns);
*pn = n;
*pns = ns;
if (! supplied) {
x = (double *) *px;
xs = (double *) *pxs;
for (xmax = xmin = x[0], i = 1; i < *pn; i++) {
if (x[i] > xmax) xmax = x[i];
if (x[i] < xmin) xmin = x[i];
}
for (i = 0; i < *pns; i++)
xs[i] = xmin + (xmax - xmin) * ((double) i) / ((double) (*pns - 1));
}
}
LVAL xsspline()
{
LVAL result;
Vector x, y, work, xs, ys;
int n, ns, error;
get_smoother_data(&x, &y, &n, &xs, &ys, &ns, TRUE);
work = (Vector) rvector(2 * n);
/* casts added JKL */
error = fit_spline(n, (RVector)x, (RVector)y, ns, (RVector)xs,
(RVector)ys, (RVector)work);
xlsave1(result);
result = mklist(2, NIL);
rplaca(result, vector_to_data(xs, ns, RE, TRUE));
rplaca(cdr(result), vector_to_data(ys, ns, RE, TRUE));
xlpop();
free_vector(x);
free_vector(y);
free_vector(xs);
free_vector(ys);
free_vector(work);
if (error) xlfail("bad data for splines");
return(result);
}
static LVAL kernel(is_reg)
int is_reg;
{
LVAL warg, targ, result;
Vector x, y, xs, ys/*, wts, wds*/;
int n, ns, error, ktype;
double width;
get_smoother_data(&x, &y, &n, &xs, &ys, &ns, is_reg);
if (! xlgetkeyarg(sk_width, &warg)) warg = NIL;
if (! xlgetkeyarg(sk_type, &targ)) targ = NIL;
width = (fixp(warg) || floatp(warg)) ? makedouble(warg) : -1.0;
/*wts = (Vector) nil;
wds = (Vector) nil; not used JKL */
if (targ == xlenter("U")) ktype = 'U';
else if (targ == xlenter("T")) ktype = 'T';
else if (targ == xlenter("G")) ktype = 'G';
else ktype = 'B';
/* casts added JKL */
error = kernel_smooth((RVector)x, (RVector)y, n, width, nil, nil,
(RVector)xs, (RVector)ys, ns, ktype);
xlsave1(result); /* redundant equation of result to NIL in macro JKL */
result = mklist(2, NIL);
rplaca(result, vector_to_data(xs, ns, RE, TRUE));
rplaca(cdr(result), vector_to_data(ys, ns, RE, TRUE));
xlpop();
free_vector(x);
free_vector(y);
free_vector(xs);
free_vector(ys);
if (error) xlfail("bad data for splines");
return(result);
}
LVAL xskernel_smooth() { return(kernel(TRUE)); }
LVAL xskernel_dens() { return(kernel(FALSE)); }
LVAL xsbase_lowess()
{
LVAL s1, s2, result;
int n, nsteps, error;
double f, delta;
Vector x, y, ys, rw, res;
s1 = xsgetsequence();
s2 = xsgetsequence();
f = makedouble(xlgetarg());
nsteps = getfixnum(xlgafixnum());
delta = makedouble(xlgetarg());
xllastarg();
n = seqlen(s1);
if (n <= 0) xlfail("sequence too short");
if (seqlen(s2) != n) xlfail("sequences not the same length");
if (data_mode(s1) == CX || data_mode(s2) == CX) xlfail("data must be real");
x = data_to_vector(s1, RE);
y = data_to_vector(s2, RE);
ys = (Vector) rvector(n);
rw = (Vector) rvector(n);
res = (Vector) rvector(n);
/* casts added JKL */
error = lowess((RVector)x, (RVector)y, n, f, nsteps, delta, (RVector)ys,
(RVector)rw, (RVector)res);
result = vector_to_data(ys, n, RE, TRUE);
free_vector(x);
free_vector(y);
free_vector(ys);
free_vector(rw);
free_vector(res);
if (error) xlfail("bad data for splines");
return(result);
}
static LVAL add_contour_point(i, j, k, l, x, y, z, v, result)
int i, j, k, l;
RVector x, y;
RMatrix z;
double v;
LVAL result;
{
LVAL pt;
double p, q;
if ((z[i][j] <= v && v < z[k][l]) || (z[k][l] <= v && v < z[i][j])) {
xlsave(pt);
pt = mklist(2, NIL);
p = (v - z[i][j]) / (z[k][l] - z[i][j]);
q = 1.0 - p;
rplaca(pt, cvflonum((FLOTYPE) (q * x[i] + p * x[k])));
rplaca(cdr(pt), cvflonum((FLOTYPE) (q * y[j] + p * y[l])));
result = cons(pt, result);
xlpop();
}
return(result);
}
LVAL xssurface_contour()
{
LVAL s1, s2, mat, result;
RVector x, y;
RMatrix z;
double v;
int i, j, n, m;
s1 = xsgetsequence();
s2 = xsgetsequence();
mat = xsgetmatrix();
v = makedouble(xlgetarg());
xllastarg();
n = seqlen(s1); m = seqlen(s2);
if (n != numrows(mat) || m != numcols(mat)) xlfail("dimensions do not match");
if (data_mode(s1) == CX || data_mode(s2) == CX || data_mode(mat) == CX)
xlfail("data must be real");
x = (RVector) data_to_vector(s1, RE);
y = (RVector) data_to_vector(s2, RE);
z = (RMatrix) data_to_matrix(mat, RE);
xlsave1(result);
result = NIL;
for (i = 0; i < n - 1; i++) {
for (j = 0; j < m - 1; j++) {
result = add_contour_point(i, j, i, j+1, x, y, z, v, result);
result = add_contour_point(i, j+1, i+1, j+1, x, y, z, v, result);
result = add_contour_point(i+1, j+1, i+1, j, x, y, z, v, result);
result = add_contour_point(i+1, j, i, j, x, y, z, v, result);
}
}
xlpop();
free_vector((Vector)x);/* casts added JKL */
free_vector((Vector)y);
free_matrix((Matrix)z, n);
return(result);
}
LVAL xsfft()
{
LVAL data, result;
CVector x;
RVector work;
int n, isign, as_list;
data = xsgetsequence();
isign = (moreargs() && xlgetarg() != NIL) ? -1.0 : 1.0;
xllastarg();
/* check and convert the data */
n = seqlen(data);
if (n <= 0) xlfail("not enough data");
data_mode(data); /* checks that data are numbers */
as_list = (listp(data)) ? TRUE : FALSE;
x = (CVector) data_to_vector(data, CX);
work = rvector(4 * n + 15);
cfft(n, (double *)x, (double *)work, isign); /* casts added JKL */
/* free internal data and return result */
result = vector_to_data((Vector)x, n, CX, as_list);/* casts added JKL */
free_vector((Vector)x);
free_vector((Vector)work);
return(result);
}